package com.ruoyi.comparison.utils;
import java.util.*;


/**
 * @author tree
 * @date 2023/9/23 15:20
 */
public class Tender {
    private String textA;//左侧文本A

    private String textB;//右侧文本B

    private String textC;//标书文本

    private int duplicateWordNum; //定义连续重复的字数

    public String getTextA() {
        return textA;
    }

    public String getTextB() {
        return textB;
    }

    public void setTextA(String textA) {
        this.textA = textA;
    }

    public void setTextB(String textB) {
        this.textB = textB;
    }

    public int getDuplicateWordNum() {
        return duplicateWordNum;
    }

    public void setDuplicateWordNum(int duplicateWordNum) {
        this.duplicateWordNum = duplicateWordNum;
    }


//    public List<String> findDuplicates(){
//        List<String> continuousWordsA = exstractContinuousWords(this.textA);
//        List<String> continuousWordsB = exstractContinuousWords(this.textB);
//        Set<String> set1 = new HashSet<String>(continuousWordsA);
//        Set<String> set2 = new HashSet<String>(continuousWordsB);
//        set1.retainAll(set2);
//        List<String> duplicates = new LinkedList<String>(set1);
//        ListIterator<String> iterator = duplicates.listIterator();
//        while(iterator.hasNext()){
//            if(this.textC.contains(iterator.next())){
//                iterator.remove();
//            }
//        }
//        return duplicates;
//
//    }

    public Tender(String textA, String textB, int continuousNum, String textC){
        this.textA = textA;
        this.textB = textB;
        this.duplicateWordNum = continuousNum;
        this.textC = textC;
    }
    public Tender(){
        this.textA = "";
        this.textB = "";
        this.duplicateWordNum = 0 ;
        this.textC = "";
    }

//    public List<String> exstractContinuousWords(String text){
//        List<String> ngrams = new ArrayList<String>();
//        for (int i = 0; i < text.length() - this.duplicateWordNum + 1; i++) {
//            String ngram = text.substring(i, i + this.duplicateWordNum);
//            if(ngram.strip().length() != 0)
//                ngrams.add(ngram);
//        }
//        return ngrams;
//    }
    /**
     * 在正则表达式中\s表示所有的空格：    匹配任何空白字符，包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。
     * 使用正则表达式,移除换行符（且不移除空格）
     *
     * @param originalStr 原始字符串
     * @return 移除换行\r、回车\n、制表\t符的字符串
     */
    public  String removeRNT(String originalStr) {
        if (originalStr == null || originalStr.isEmpty()) {
            return originalStr;
        }
        return originalStr.replaceAll("[\t\n\r]","");
    }

    /**
     * 移除字符串中所有的空白格（包含换行\r、回车\n、制表\t符）
     *
     * @param str 原始串
     * @return 无空格后的串
     */
    public String trimAllWhitespace(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        int len = str.length();
        StringBuilder sb = new StringBuilder(str.length());
        for (int i = 0; i < len; i++) {
            char c = str.charAt(i);
            if (!Character.isWhitespace(c)) {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    // 替换标点和空格方法
    public static String replaceAllPunctuationAndBlank(String s) {
        if (s.equals("")){
            return "";
        }
        String regex = "\\pP|\\p{Space}]";
        String punctuation = "[.,?;!，。'？！、：“”]";
        return s.replaceAll(regex, "");
    }
    /**
     * 时间换空间，暴力求解，解决动态规划求所有子串需要超大二维数组产生堆溢出的问题
     * @param s1
     * @param s2
     * @param minLen
     * @param s3
     * @return
     */
    public List<String> findAllCommonSubstrings(String s1, String s2, int minLen, String s3) {
        String noPuncTenderString = replaceAllPunctuationAndBlank(s3);
        HashSet<String> keySet = new HashSet<>();
        for (int i = 0; i < s1.length(); i++) {
            for (int j = 0; j < s2.length(); j++) {
                int m = i;
                int n = j;
                int len = 0;
                int begin = 0;
                while (m < s1.length() && n < s2.length() && s1.charAt(m) == s2.charAt(n)) {
                    if(len == 0){
                        begin = m;
                    }
                    len++;
                    if(len >= minLen) {
                        String key = s1.substring(begin, begin + len);
                        String temp = key;
                        temp = removeRNT(temp);
                        temp = trimAllWhitespace(temp);
                        temp = replaceAllPunctuationAndBlank(temp);
                        if(temp.length() >= minLen && !noPuncTenderString.contains(temp)
                            && !temp.contains("限公司") && !temp.contains("存在控股关联")
                            && !temp.contains("拟分包项") && !temp.contains("列入行贿")
                            && !temp.contains("本招标项目") && !temp.contains("投标函") && !temp.contains("投标人")
                            && !temp.contains("法人代表或委托代理人") && !temp.contains("法定代表人")
                            &&!temp.contains("招标编号")) {
                            keySet.add(key);
                        }
                    }
                    m++;
                    n++;
                }
            }
        }
        List<String> keyList = new ArrayList<>(keySet);
        //将列表按元素长度升序排列
        keyList.sort(Comparator.comparingInt(String::length));
        /*
        for(String str : keyList ){
            System.out.println("开始:" + str + ":结束" + "长度:" + str.length());
        }
         */
        Iterator<String> iterator = keyList.iterator();
        //确保任意两个元素均不相互包含
        while(iterator.hasNext()){
            String key = iterator.next();
            for(String str : keyList){
                if(str.contains(key) && !str.equals(key)){
                    iterator.remove();
                    break;
                }
            }
        }
        return keyList;
    }

    /**
     * 动态规划求解所有子串，适用于二维数组比较小的情况
     * @param inputA
     * @param inputB
     * @param continuous
     * @param inputC
     * @return
     */
    public  List<String> exactAllCommonSeq(String inputA, String inputB, int continuous, String inputC) {
        //连续最小重复的字数为11
        if(continuous < 11)
            continuous = 11;
        //把字符串转成字符数组
        char[] arr1 = inputA.toCharArray();
        char[] arr2 = inputB.toCharArray();
        // 把两个字符串分别以行和列组成一个二维矩阵
        int[][] temp = new int[arr1.length][arr2.length];
        //初始化二维矩阵中的第一行
        for (int i = 0; i < arr2.length; i++) {
            temp[0][i] = (arr1[0] == arr2[i]) ? 1 : 0;
        }
        //初始化二维矩阵中的第一列
        for (int j = 0; j < arr1.length; j++) {
            temp[j][0] = (arr2[0] == arr1[j]) ? 1 : 0;
        }
        //嵌套for循环：比较二维矩阵中每个点对应行列字符中否相等，相等的话值设置为1，否则设置为0
        for (int i = 1; i < arr1.length; i++) {
            for (int j = 1; j < arr2.length; j++) {
                if (arr1[i] == arr2[j]) {
                    //对角线上一个值加1，方便求取每个公共子序列的长度
                    temp[i][j] = temp[i - 1][j - 1] + 1;
                } else {
                    temp[i][j] = 0;
                }
            }
        }
        Set<String> keySet = new HashSet<>();
        List<Map<String, Integer>> list = new ArrayList<>();
        //依次遍历对角矩阵的对角线
        for (int i = 0; i < arr1.length; i++) {
            for (int j = 0; j < arr2.length; j++) {
                Map<String, Integer> map = new HashMap<>();
                if (temp[i][j] != 0 && temp[i][j] >= continuous) {
                    if (temp[i - 1][j - 1] == temp[i][j] - 1) {
                        if (i - 1 > 0 && j - 1 > 0 && i + 1 < arr1.length && j + 1 < arr2.length && temp[i - 1][j - 1] != 0 && temp[i + 1][j + 1] == 0) {
                            map.put("row", i);
                            map.put("column", j);
                            map.put("length", temp[i][j]);
                            list.add(map);
                            String key = getsubString(inputA, i, temp[i][j]);
                            if(!inputC.contains(key)) {
                                keySet.add(getsubString(inputA, i, temp[i][j]));
                            }
                        } else if ((i + 1 == arr1.length || j + 1 == arr2.length)) {
                            map.put("row", i);
                            map.put("column", j);
                            map.put("length", temp[i][j]);
                            list.add(map);
                            String key = getsubString(inputA, i, temp[i][j]);
                            if(!inputC.contains(key)) {
                                keySet.add(getsubString(inputA, i, temp[i][j]));
                            }
                        }
                    }
                }
            }
        }
        /*
        Set<String> resultSet = new HashSet<>();
        if (!list.isEmpty()) {
            for (Map<String, Integer> map : list) {
                String s = getsubString(inputA, map.get("row"), map.get("length"));
                if(!inputC.contains(s)) {
                    resultSet.add(s);
                }

            }
        }
        for(String str : resultSet ){
            System.out.println("开始:" + str + ":结束" + "长度:" + str.length());
        }
         */
        List<String> keyList = new ArrayList<>(keySet);
        //将列表按元素长度升序排列
        keyList.sort(Comparator.comparingInt(String::length));
        /*
        for(String str : keyList ){
            System.out.println("开始:" + str + ":结束" + "长度:" + str.length());
        }
         */
        Iterator<String> iterator = keyList.iterator();
        //确保任意两个元素均不相互包含
        while(iterator.hasNext()){
            String key = iterator.next();
            for(String str : keyList){
                if(str.contains(key) && !str.equals(key)){
                    iterator.remove();
                    break;
                }
            }
        }
        for(String str : keyList ){
            System.out.println("开始:" + str + ":结束" + "长度:" + str.length());
        }
        return keyList;
    }

    /**
     * 根据坐标位置及子串长度获取子串内容
     * @param s
     * @param a
     * @param b
     * @return
     */
    public static String getsubString(String s, int a, int b) {
        String s1 ;
        s1 = s.substring(a - b + 1, a + 1);
        return s1;
    }


}
